<?php
  /***************************************************************
   * @file: route.php
   * @author: Neo
   * @mail: xq262144@gmail.com
   * @date: 
   * @description:
   * this file is the route controlling of the dispatcher
   ***************************************************************/

  if (!defined('SYS_BASEPATH')) { echo "No script access allowed!"; header("HTTP/1.0 404 Not Found"); } 
  
  //get the set of the default route
  if (!defined('SYS_CONFIG')) { report_error('Config not found!'); }
  require_once(SYS_CONFIG . '/route.php'); 
  
  //technic: check user-agent to determine mobile edition viewing
  //only opera mobile, standard mobile client can view this page in mobile
  ///////////////////////////////////////////////
  if (defined('WAP_REG') && isset($_SERVER['HTTP_USER_AGENT']) && 
    preg_match(WAP_REG, $_SERVER['HTTP_USER_AGENT'])){
      define('WAP', '');
  }
  /////////////////////////////////////////////
  //get the route from the server variable $_SERVER['PATH_INFO']
  if (!isset($_SERVER['PATH_INFO']) || $_SERVER['PATH_INFO'] == '/') {
    if (!isset($routes['default'])){
      report_error('Default route not found!');
    }
    else{
      header('Location:' . SYS_BASE_URL . $routes['default']);
      die; 
    }    
  }
  else {
    $raw_route = $_SERVER['PATH_INFO'];  
  }
  
  //parse the route to class, method and parameters
  $raw_route = substr($raw_route, 1);
  $route_class = null;
  $route_method = null;
  $route_params = null;
  $route_array = explode('/', $raw_route);
  if (isset($route_array[0]) && !empty($route_array[0]) 
    && 0 === strcasecmp($route_array[0], 'mobile') && !defined('WAP')){
        define('WAP', '');
        array_splice($route_array, 0, 1);
    }
    //modified xq262144
  $route_array = array_filter($route_array, create_function('$var', 'return !empty($var);'));
  
  if (empty($route_array)){
      if (isset($routes['default'])){
          header('Location: ' . SYS_BASE_URL . '/mobile' . $routes['default']);
          die;
      }
      else{
          report_error('Default route not found!');
      }
  }
  
  $route_class = trim($route_array[0]);
  $route_method = trim(!isset($route_array[1]) || $route_array[1] == '' ?  'index' : $route_array[1]);
  
  if ($route_class{0} == '_') {
    //the input class is an inner class
    report_notice('Route is inner class');  
  }
  if ($route_method{0} == '_') {
    //the input method is an inner method
    report_notice('Route is inner method');  
  }
  if (isset($routes['rewrite'])){
      //modified xq262144
      foreach($routes['rewrite'] as &$value){
          if (0 === strcasecmp($value['from']['class'], $route_class) &&
            0 === strcasecmp($value['from']['method'], $route_method)){
                if (isset($value['to']['class'])) $value['to']['class'] = trim($value['to']['class']);
                if (isset($value['to']['method'])) $value['to']['method'] = trim($value['to']['method']);
                $route_class = isset($value['to']['class']) && 
                    !empty($value['to']['class']) ? $value['to']['class'] : $value['from']['class'];
                $route_method = isset($value['to']['method']) &&
                    !empty($value['to']['method']) ? $value['to']['method'] : $value['from']['method'];
            }
      }
  }    
  if (count($route_array) > 2) {
	$route_params = array_slice($route_array, 2);
  }

  function route_error_handling($code, $msg, $file, $line) {
    sys_error_handler(E_ERROR, $msg, $file, $line);
    die;
  }

  //set the error handler of current route parser
  set_error_handler('route_error_handling');
  
  //fetch the controller class and invoke the method
  if (file_exists(SYS_CONTROLLER . "/${route_class}.php")) { 
    require_once(SYS_CONTROLLER . "/${route_class}.php");
    $route_classname = $route_class . '_controller';
    $route_obj = new $route_classname(); 
    if (!$route_obj instanceof Controller || !method_exists($route_obj, $route_method)) {
      report_notice('Route not exist');
    }
    else{
      //restore the error handler
      restore_error_handler();
      
      //do the user function invoke and param. passing
      call_user_func_array(array($route_obj, $route_method), $route_params);
    }
  }
  else{
    report_notice('Route not exist');
  }